package org.turnlink.sclm.dao.hibernate;

import java.util.LinkedList;
import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.turnlink.sclm.dao.ContactListDao;
import org.turnlink.sclm.model.ContactContactList;
import org.turnlink.sclm.model.ContactContactListId;
import org.turnlink.sclm.model.ContactList;

//This will make easier to autowired
@Repository("contactListDao")
// Default is read only
@Transactional
public class ContactListDaoHibernate implements ContactListDao {

	private HibernateTemplate hibernateTemplate;
	
	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		hibernateTemplate = new HibernateTemplate(sessionFactory);
	}

	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#deleteByAccountAndListName(java.lang.Integer, java.lang.String)
	 */
	@Transactional(readOnly = false)
	public void removeByAccountAndListName(Integer accountId, String listName) {
		ContactList contactList = findByAccountAndListName(accountId, listName);
		if (contactList == null) return;
		hibernateTemplate.bulkUpdate("delete ContactContactList cl where cl.id.contactListId = ? ", contactList.getContactListId());
		hibernateTemplate.delete(contactList);
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#deleteByAccountAndListId(java.lang.Integer, java.lang.Integer)
	 */
	@Transactional(readOnly = false)
	public void removeByAccountAndListId(Integer accountId, Integer listId) {
		ContactList contactList = findByAccountAndListId(accountId, listId);
		if (contactList == null) return;
		hibernateTemplate.bulkUpdate("delete ContactContactList cl where cl.id.contactListId = ? ", listId);
		hibernateTemplate.delete(contactList);
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#findByAccountAndListName(java.lang.Integer, java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	public ContactList findByAccountAndListName(Integer accountId, String listName) {
		List<ContactList> res = hibernateTemplate.find("from ContactList where accountId = ? and listName = ? ", new Object[] { accountId, listName});
		return res == null || res.isEmpty()
			? null
			: res.get(0);
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#findByAccountAndListId(java.lang.Integer, java.lang.Integer)
	 */
	@SuppressWarnings("unchecked")
	public ContactList findByAccountAndListId(Integer accountId, Integer listId) {
		List<ContactList> res = hibernateTemplate.find("from ContactList where accountId = ? and listId = ? ", new Object[] { accountId, listId});
		return res == null || res.isEmpty()
			? null
			: res.get(0);
	}
	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#findByAccountId(java.lang.Integer)
	 */
	@SuppressWarnings("unchecked")
	public List<ContactList> findByAccountId(Integer accountId) {
		return hibernateTemplate.find("from ContactList where accountId = ? " , accountId);
	}

	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#saveOrUpdate(java.lang.Integer, org.turnlink.sclm.model.ContactList)
	 */
	@Transactional(readOnly = false)
	public void saveOrUpdate(ContactList contactList) {
		hibernateTemplate.saveOrUpdate(contactList);
	}

	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#addContactsToList(java.lang.Integer, java.lang.String, java.util.List)
	 */
	@Transactional(readOnly = false)
	public void addContactsToList(Integer accountId, String listName, List<Integer> contactIds) {
		ContactList contactList = findByAccountAndListName(accountId, listName);
		Integer contactListId = contactList.getContactListId();
		List<ContactContactList> contacts = new LinkedList<ContactContactList>();
		for (Integer contactId : contactIds) {
			contacts.add(new ContactContactList(new ContactContactListId( contactId, contactListId )));
		}
		hibernateTemplate.saveOrUpdateAll(contacts);
	}

	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#findContactsFromList(java.lang.Integer, java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	public List<ContactContactList> findContactsFromList(Integer accountId, String listName) {
		ContactList contactList = findByAccountAndListName(accountId, listName);
		return hibernateTemplate.find("from ContactContactList where id.contactListId = ? ", contactList.getContactListId()); 
	}

	/*
	 * (non-Javadoc)
	 * @see org.turnlink.sclm.dao.ContactListDao#removeContactsFromList(java.lang.Integer, java.lang.String, java.util.List)
	 */
	@Transactional(readOnly = false)
	public void removeContactsFromList(Integer accountId, String listName, List<Integer> contactIds) {
		ContactList contactList = findByAccountAndListName(accountId, listName);
		Integer contactListId = contactList.getContactListId();
		for (Integer contactId: contactIds) {
			hibernateTemplate.bulkUpdate("delete ContactContactList where id.contactListId = ? and id.contactId = ?", contactListId, contactId);	
		}
	}

}
